// 创建一个类型接口
interface IRequest {
    /**
     * 统一资源定位符(链接资源地址)
     */
    url: string;
    /**
     * 获取url的方法
     */
    method?: 'GET' | 'POST';
    /**
     * 参数
     */
    params?: Record<string, any>;
    /**
     * 数据
     */
    data?: Record<string, any>;
    /**
     * 标题
     */
    headers?: Record<string, string>;
}
// 接口处传递的参数
interface IResponse {
    code: number;
    show: number;
    msg: string;
    data: Record<string, any>[] | Record<string, any>;
}

// 暴露异步函数方法request 参数类型是IRequest
export async function request(opt: IRequest) {
    // 判断类型为opt中的url的类型不为string或 url的长度为0时
    if (typeof opt.url != 'string' || opt.url.length == 0) {
        // 抛出异常
        throw new Error('url不能为空！');
    }
    // 如果params有值
    if (opt.params) {
        // URLSearchParams()是个构造函数，将返回一个可以操作查询字符串的对象
        opt.url += '?' + new URLSearchParams(opt.params);
    }
    // 接收一个URL作为参数 发起GET请求
    const response = await fetch(opt.url, {
        //  请求的方式是'GET' | 'POST' ||  'GET' 意为请求方式是get跟post的比较 或get
        method: opt.method || 'GET',
        headers: opt.headers || {
            // 这是一个默认的头部对象，如果opt.headers没有值，就会作为请求的头部，这是送到服务器的数据类型是JSON
            'Content-Type': 'application/json',
        },
        // body的值由一个三元运算符构成
        body: opt.data ? JSON.stringify(opt.data) : undefined,
    })
        // then函数主要用于处理异步操作成功后的逻辑 是Promise对象的一个方法
        // 当fetch函数从服务器获取数据，就能用then函数处理获取到的数据，
        // then接收两个参数，一个回调函数和一个错误处理函数
        // 第一个回调函数接收两个参数，第一个接收处理的数据，第二个接收Response对象
        // 第二个错误处理函数，在处理出现错误的时候调用，并传入一个Error对象
        .then((res) => {
            // 这里的then调用的是resolve的参数
            if (res.status === 200) {
                // 如果值为200，就返回res.json()
                return res.json();
            }
            if (res.status === 404) {
                // 当值为404时，返回Promise成功时的参数
                return Promise.resolve({
                    // 接口处传来的code为404
                    code: 404,
                    // 打印出的信息为
                    message: '请求接口不存在！',
                });
            }
            if (res.status === 500) {
                return Promise.resolve({ code: 500, message: '服务器错误！' });
            }
            return Promise.resolve({ code: 999, message: '未知错误！' });
        })
        .then((res: IResponse) => {
            if (res.show == 1) {
                // 会话ID不能为空
                console.log(res.msg);
            }
            if (res.code == 1) {
                // instanceof Object 检查变量是否是一个普通的对象  这里是对象返回true 是数组也返回true
                if (res.data && res.data instanceof Object) {
                    // 为真时 resolve的参数为 status返回真，data返回res.data的值
                    return Promise.resolve({ status: true, data: res.data });
                }
                // 当code输出为1时 Promise.resolve从未完成到成功 的参数为 status值为true,data的值为一个对象 key为data value为res
                return Promise.resolve({ status: true, data: { data: res } });
            }
            return Promise.resolve({ status: false, data: res });
        });

    return response;
}
